package main.tileMap;

import main.entities.Entity;
import main.entities.EntityFactory;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.tiled.TiledMap;



public class Map {
	

	/** The size of the tiles - used to determine the amount to draw */
	private static final int TILE_SIZE = 32;

	Entity player;
	
	/** The player's x position in tiles */
	public float playerX = 15;
	/** The player's y position in tiles */
	public float playerY=8;

	/** The width of the display in tiles */
	private int widthInTiles;
	/** The height of the display in tiles */
	private int heightInTiles;

	/** The offset from the center of the screen to the top edge in tiles */
	private int topOffsetInTiles;
	/** The offset from the center of the screen to the left edge in tiles */
	private int leftOffsetInTiles;

	/** The map that we're going to drive around */
	private TiledMap map;
	

	private boolean[][] blocked;

	private String string;

	private boolean b;



	
	public Map(String string, boolean b) throws SlickException {
		this.string =string;
		this.b = b;

	}
	
	public void init(GameContainer gc, StateBasedGame sbg, EntityFactory eFactory) throws SlickException {
		this.map = new TiledMap(string,b);
		// load the tilemap created the TileD tool 

		// build a collision map based on tile properties in the TileD map
		blocked = new boolean[map.getWidth()][map.getHeight()];
		for (int x=0;x<map.getWidth();x++) {
			for (int y=0;y<map.getHeight();y++) {
				int tileID = map.getTileId(x, y, 0);
				String value = map.getTileProperty(tileID, "blocked", "false");
				if ("true".equals(value)) {
					blocked[x][y] = true;
				}else{
					blocked[x][y]= false;
				}
			}
		}
		this.player = eFactory.createPlayer(gc.getWidth()/2, gc.getHeight()/2, this);
		// caculate some layout values for rendering the tilemap. How many tiles
		// do we need to render to fill the screen in each dimension and how far is
		// it from the centre of the screen
		widthInTiles = gc.getWidth() / TILE_SIZE;
		heightInTiles = gc.getHeight() / TILE_SIZE;
		topOffsetInTiles = heightInTiles / 2;
		leftOffsetInTiles = widthInTiles / 2;
	}
	
	public boolean blocked(float x, float y) {
		return blocked[(int) x][(int) y];
	}
	


	public void render(GameContainer gc, StateBasedGame sbg, Graphics g) {
		// draw the appropriate section of the tilemap based on the centre (hence the -(TANK_SIZE/2)) of
		// the player
		int playerTileX = (int) playerX;
		int playerTileY = (int) playerY;
		// caculate the offset of the player from the edge of the tile. As the player moves around this
		// varies and this tells us how far to offset the tile based rendering to give the smooth
		// motion of scrolling
		int playerTileOffsetX = (int) ((playerTileX - playerX) * TILE_SIZE);
		int playerTileOffsetY = (int) ((playerTileY - playerY) * TILE_SIZE);
		// render the section of the map that should be visible. Notice the -1 and +3 which renders
		// a little extra map around the edge of the screen to cope with tiles scrolling on and off
		// the screen		
		map.render((int)playerTileOffsetX - (int)(player.getWidth()/2), 
				(int)playerTileOffsetY - ((int)player.getheigth()), 
				 (int)playerTileX - leftOffsetInTiles - 1, 
				 (int)playerTileY - topOffsetInTiles - 1,
				 widthInTiles + 3, heightInTiles + 3);
		player.render(g);
	}

	public void keyPressed(int key, char c) {
		player.keyPressed(key, c);
		
	}

	public void keyReleased(int key, char c) {
		player.keyReleased(key, c);
		
	}

	public void update(GameContainer gc, StateBasedGame sbg, int g) {
		player.update(gc, sbg, g);
		
	}

	public float getWidth() {
		// TODO Auto-generated method stub
		return map.getWidth();
	}

	public float getHeight() {
		// TODO Auto-generated method stub
		return map.getHeight();
	}

	

}
